﻿using System;

namespace Apewer.Web
{

    /// <summary>WebAPI 控制器基类。</summary>
    /// <remarks>控制器具有 Independent 特性时，不匹配 Function，且忽略 Initializer 返回值。</remarks>
    public abstract class ApiController
    {

        internal Func<ApiController, bool> _func = null;
        internal Action<ApiController> _action = null;
        internal Action<ApiController> _default = null;
        internal ApiOptions _options = null;

        /// <summary>获取 API 请求模型。</summary>
        public ApiRequest Request { get; internal set; }

        /// <summary>获取 API 响应模型。</summary>
        public ApiResponse Response { get; internal set; }

        /// <summary>创建控制器实例。可通过初始化程序返回布尔值，以执行 Function 解析。</summary>
        /// <param name="initializer">初始化程序。当返回 False 时等同于声明 Independent，将不再匹配 Function 和 Default。</param>
        /// <param name="default">在匹配 Function 且失败后执行的方法。</param>
        /// <remarks>执行顺序：构造函数 -> Initializer -> Function -> Default -> Dispose</remarks>
        public ApiController(Func<ApiController, bool> initializer = null, Action<ApiController> @default = null)
        {
            _func = initializer;
            _default = @default;
        }

        /// <summary>创建控制器实例。可通过初始化程序返回布尔值，以执行 Function 解析。</summary>
        /// <param name="initializer">初始化程序。</param>
        /// <param name="default">在匹配 Function 且失败后执行的方法。</param>
        /// <remarks>执行顺序：构造函数 -> Initializer -> Function -> Default -> Dispose</remarks>
        public ApiController(Action<ApiController> initializer, Action<ApiController> @default = null)
        {
            _func = (c) =>
            {
                initializer?.Invoke(this);
                return true;
            };
            _default = @default;
        }

    }

    /// <summary>WebAPI 控制器基类。</summary>
    /// <remarks>控制器具有 Independent 特性时，不匹配 Function，且忽略 Initializer 返回值。</remarks>
    public abstract class ApiController<T> : ApiController where T : ApiController
    {

        static Func<ApiController, bool> ToBaseFunc(Func<T, bool> current)
        {
            if (current == null) return null;
            return new Func<ApiController, bool>(c => current.Invoke((T)c));
        }

        static Action<ApiController> ToBaseAction(Action<T> current)
        {
            if (current == null) return null;
            return new Action<ApiController>(c => current.Invoke((T)c));
        }

        /// <summary>创建控制器实例。可通过初始化程序返回布尔值，以执行 Function 解析。</summary>
        /// <param name="initializer">初始化程序。当返回 False 时等同于声明 Independent，将不再匹配 Function 和 Default。</param>
        /// <param name="default">在匹配 Function 且失败后执行的方法。</param>
        /// <remarks>执行顺序：构造函数 -> Initializer -> Function -> Default -> Dispose</remarks>
        public ApiController(Func<T, bool> initializer = null, Action<T> @default = null) : base(ToBaseFunc(initializer), ToBaseAction(@default)) { }

        /// <summary>创建控制器实例。可通过初始化程序返回布尔值，以执行 Function 解析。</summary>
        /// <param name="initializer">初始化程序。</param>
        /// <param name="default">在匹配 Function 且失败后执行的方法。</param>
        /// <remarks>执行顺序：构造函数 -> Initializer -> Function -> Default -> Dispose</remarks>
        public ApiController(Action<T> initializer, Action<T> @default = null) : base(ToBaseAction(initializer), ToBaseAction(@default)) { }

    }

}
